﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace ADSync2.EngineComponents
{
	/// <summary>
	/// Class controls synchronization history
	/// Reads/Writes historical synchronization state
	/// </summary>
	public class SyncHistory
	{
		#region Constants
		private String FILE_NAME = "SyncHistory.dat";
		#endregion

		#region Properties
		public Dictionary<String,SyncServer> DomainSyncStates
		{
			get;
			set;
		}
		#endregion

		#region Constructors
		public SyncHistory()
		{
			this.DomainSyncStates = new Dictionary<string,SyncServer>(StringComparer.OrdinalIgnoreCase);
		}
		#endregion

		#region Public Instance Methods
		public void WriteSynchronizationHistory()
		{
			try
			{
				String SynchronizationHistoryFile = String.Format(@"{0}\{1}",
					Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath),
					FILE_NAME);

				if (File.Exists(SynchronizationHistoryFile))
				{
					File.Delete(SynchronizationHistoryFile);
				}

				foreach (KeyValuePair<String, SyncServer> SyncRecord in this.DomainSyncStates)
				{
					using( StreamWriter WriterObject = new StreamWriter(SynchronizationHistoryFile, true) )
					{
						WriteSynchronizationHistory(WriterObject, SyncRecord.Key,SyncRecord.Value);
						WriterObject.Close();
					}
				}
			}
			catch (Exception eX)
			{
				throw new Exception(string.Format("{0}::{1}",new StackFrame(0,true).GetMethod().Name,eX.Message));
			}
		}

		/// <summary>
		/// Updates synchronization history with new state
		/// </summary>
		/// <param name="DomainFqdn"></param>
		/// <param name="ServerSynchronizationState"></param>
		public void UpdateSyncHistory(String DomainFqdn, SyncServer SynchronizationServer)
		{
			if (!this.DomainSyncStates.ContainsKey(DomainFqdn))
			{
				this.DomainSyncStates.Add(DomainFqdn, SynchronizationServer);
			}
			else
			{
				this.DomainSyncStates[DomainFqdn] = SynchronizationServer;
			}
		}
		#endregion

		#region Public Static Methods
		/// <summary>
		/// Method reads historical synchronization history
		/// Source file: SyncHistory.dat
		/// </summary>
		/// <returns></returns>
		public static SyncHistory ReadSynchronizationHistory()
		{
			String FILE_NAME = "SyncHistory.dat";

			try
			{
				SyncHistory SynchronizationHistory = new SyncHistory();

				String SynchronizationHistoryFile = String.Format(@"{0}\{1}",
					Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath),
					FILE_NAME);


				if( File.Exists(SynchronizationHistoryFile) )
				{
					using( StreamReader ReaderObject = new StreamReader(SynchronizationHistoryFile) )
					{
						while(ReaderObject.Peek() >= 0)
						{
							String[] SyncRecord = ReaderObject.ReadLine().Split(',');
							if(SyncRecord.Length == 4)
							{
								if( !SynchronizationHistory.DomainSyncStates.ContainsKey(SyncRecord[0]) )
								{
									SynchronizationHistory.DomainSyncStates.Add(SyncRecord[0],
										new SyncServer( SyncRecord[1], SyncRecord[2], 0, long.Parse(SyncRecord[3]) )
									);
								}

							}
						}
					}
				}

				return SynchronizationHistory;
			}
			catch (Exception eX)
			{
				throw new Exception(string.Format("{0}::{1}",new StackFrame(0,true).GetMethod().Name,eX.Message));
			}
		}
		#endregion

		#region Private Methods
		private static void WriteSynchronizationHistory(StreamWriter WriterObject, String DomainFqdn, SyncServer ServerSynchronizationState)
		{
			try
			{
				WriterObject.WriteLine(String.Format("{0},{1},{2},{3}",
					DomainFqdn,
					ServerSynchronizationState.ServerFqdn,
					ServerSynchronizationState.ServerGuid,
					ServerSynchronizationState.HighestCommittedUSN) );
			}
			catch (Exception eX)
			{
				throw new Exception(string.Format("{0}::{1}",new StackFrame(0,true).GetMethod().Name,eX.Message));
			}
		}
		#endregion
	}
}
